Appearance
函数式组件
本节目标:理解“函数式组件”的核心思路,并能把它用于实际开发或面试表达。 ==之前创建的锚点标题组件是比较简单,没有管理任何状态,也没有监听任何传递给它的状态,也没有生命周期方法。实际上,它只是一个接受一些==
prop==的函数。在这样的场景下,我们可以将组件标记为==functional==,这意味它无状态==(==没有====响应式数据==)==,也没有实例==(==没有==this==上下文==)==。一个====函数式组件====就像这样:==
Vue.component('my-component', {
functional: true,
// Props是可选的
props: {
// ...
},
//为了弥补缺少的实例
//提供第二个参数作为上下文
render: function (createElement, context) {
// ...
}
})==注意:在== 2.3.0 ==之前的版本中,如果一个函数式组件想要接收== prop==,则== props ==选项是必须的。在== 2.3.0 ==或以上的版本中,你可以省略== props ==选项,所有组件上的== attribute ==都会被自动隐式解析为== prop==。== ==当使用函数式组件时,该引用将会是== HTMLElement==,因为他们是无状态的也是无实例的。== ==在== 2.5.0 ==及以上版本中,如果你使用了====单文件组件====,那么基于模板的函数式组件可以这样声明:==
<template functional></template>==组件需要的一切都是通过== context ==参数传递,它是一个包括如下字段的对象:==
props==:提供所有==prop==的对象==children==:==VNode==子节点的数组==slots==:一个函数,返回了包含所有插槽的对象==scopedSlots==:==(2.6.0+)==一个暴露传入的作用域插槽的对象。也以函数形式暴露普通插槽。==data==:传递给组件的整个====数据对象====,作为==createElement==的第二个参数传入组件==parent==:对父组件的引用==listeners==:==(2.3.0+)==一个包含了所有父组件为当前组件注册的事件监听器的对象。这是==data.on==的一个别名。==injections==:==(2.3.0+)==如果使用了==inject==选项,则该对象包含了应当被注入的==
property==。==
==在添加== functional: true ==之后,需要更新我们的锚点标题组件的渲染函数,为其增加== context ==参数,并将== this.$slots.default ==更新为== context.children==,然后将== this.level ==更新为== context.props.level==。== ==因为函数式组件只是函数,所以渲染开销也低很多。== ==在作为包装组件时它们也同样非常有用。比如,当你需要做这些时:==
- ==程序化地在多个组件中选择一个来代为渲染;==
- ==在将==
children==、==props==、==data==传递给子组件之前操作它们。==
==下面是一个== smart-list ==组件的例子,它能根据传入== prop ==的值来代为渲染更具体的组件:==
var EmptyList = { /* ... */ }
var TableList = { /* ... */ }
var OrderedList = { /* ... */ }
var UnorderedList = { /* ... */ }
Vue.component('smart-list', {
functional: true,
props: {
items: {
type: Array,
required: true
},
isOrdered: Boolean
},
render: function (createElement, context) {
function appropriateListComponent() {
var items = context.props.items
if (items.length === 0) return EmptyList
if (typeof items[0] === 'object') return TableList
if (context.props.isOrdered) return OrderedList
return UnorderedList
}
return createElement(
appropriateListComponent(),
context.data,
context.children
)
}
})